<template>
  <div
    class="map-div-xyz"
    :style="{ height: divHeight + 'px', width: divWidth}"
  >
    <div id="my-map"></div>
    <!-- <div id="position"><img
        src="http://api.tianditu.gov.cn/v4.0/image/marker-icon.png"
        alt="示例定位图标"
      /></div> -->

      <!-- 坐标显示区域 -->
    <div
      class="custom-mouse-position"
      id="mouse-position"
    ></div>

    <!-- 缩放控件 -->
    <div class="custom-zoom-position" id="zoom-position">
    </div>

    <search-input
      ref="SearchInput"
      :map="map"
      @getResults="handleResult"
      @clearMarkers="clearMarkers"
      @selectPoint="selectPoint"
    ></search-input>

    <!-- 控件栏 -->
    <control-div ref="ControlDiv" @changeLayer="changeLayer"></control-div>

  </div>
</template>

<script>
import 'ol/ol.css'
import XYZ from 'ol/source/XYZ';
import VectorSource from 'ol/source/Vector';
import Group from 'ol/layer/Group';
import { Tile, Image } from 'ol/layer';
import Vector from 'ol/layer/Vector'
import View from 'ol/View'
import Map from 'ol/Map'
import Geolocation from 'ol/Geolocation.js';
import Overlay from 'ol/Overlay';
import Feature from "ol/Feature";


import SearchInput from './search.vue'
import ControlDiv from './control.vue'
import { Point } from 'ol/geom';
import { Style, Icon, Text, Fill, Stroke } from 'ol/style';

import { fromLonLat, transform } from 'ol/proj'
import { defaults, MousePosition } from 'ol/control';
import { createStringXY } from 'ol/coordinate';

// import '@/utils/ol-util'
export default {
  components: {
    SearchInput,
    ControlDiv
  },
  data () {
    return {
      divHeight: window.innerHeight - 70,
      divWidth: document.body.clientWidth,
      tdUrl: process.env.VUE_APP_TDT_LAYER_API + process.env.VUE_APP_TDT_TK,
      //'ter_w', 'cta_w'
      // 影像混合
      satellitepoi: ['img_w', 'cia_w'],
      lyr: ['vec_w', 'cva_w'],
      map: null,
      vecLayer: null,
      img_layer: null,
      vec_layer: null,
    }
  },
  methods: {
    mapInit () {
      this.vecLayer = new Vector({
        source: new VectorSource()
      })
      this.img_layer = this.getTileLayer(this.satellitepoi);
      this.vec_layer = this.getTileLayer(this.lyr);
      this.map = new Map({
        // 让id为map的div作为地图的容器
        target: 'my-map',
        // 设置地图图层
        layers: [
          this.vec_layer,
          this.vecLayer
        ],
        // 设置显示地图的视图
        view: new View({
          center: fromLonLat([116.38917, 39.90336]),
          zoom: 12,
          // projection: "EPSG:4326",
          maxZoom: 18,
          minZoom: 1,
        }),
        controls: defaults({
          zoom: true,
          zoomOptions: {
            className: 'custom-zoom-position',
            target: document.getElementById('zoom-position'),
            zoomInTipLabel: '',
            zoomOutTipLabel: '',
          },
          rotate: false
        })
      });
      this.addMarker([116.38917, 39.90336], '北京');
      this.addControls();
    },
    // 添加控件
    addControls () {
      // 向地图添加 MousePosition
      var mousePositionControl = new MousePosition({
        //坐标格式
        coordinateFormat: createStringXY(5),
        //地图投影坐标系（若未设置则输出为默认投影坐标系下的坐标）
        projection: "EPSG:4326",
        //坐标信息显示样式类名，默认是'ol-mouse-position'
        className: "custom-mouse-position",
        //显示鼠标位置信息的目标容器
        target: document.getElementById("mouse-position"),
        //未定义坐标的标记
        undefinedHTML: "&nbsp;"
      });
      this.map.addControl(mousePositionControl);
    },
    // 检索结束后的回调函数
    searchCompleteCallback (result) {
      console.log('回调结果', result);
      this.$emit('getResults', result.getPois());
    },
    // 获取瓦片源数据
    getTileSource (lyr, url) {
      // let ol = this.$ol;
      let newUrl = url.replace('{lyr}', lyr);
      newUrl = newUrl.replace('{n}', Math.floor(Math.random() * 8));
      return new XYZ({
        crossOrigin: 'anonymous',
        url: newUrl
      });
    },
    // 获取瓦片层
    getTileLayer (lyr) {
      // let ol = this.$ol;
      return new Group({
        layers: lyr.map(item => {
          var tile = new Tile({
            crossOrigin: 'anonymous',
            source: this.getTileSource(item, this.tdUrl)
          });
          // 设置key
          tile.key = item;
          return tile;
        })
      });
    },
    // 删除所有标注点以及对应标签
    clearMarkers () {
      var overlays = this.map.getOverlays();
      overlays.forEach(item => {
        if (item.id === 'marker') {
          this.map.removeOverLay(item);
        }
      })
    },
    // 处理检索结果
    handleResult (result) {
      console.log('获取检索结果', result);
      this.clearMarkers();
    },
    // 选择搜索列表项并标注
    selectPoint (item) {
      var lnglat = item.lonlat.split(',');

      this.addMarker(item.lonlat.split(','), item.name);

      // 将标注点更换为中心点
      this.changeCenterZoom(lnglat);
    },
    computeHeight () {
      let that = this;
      window.onresize = () => {
        return (() => {
          that.divHeight = window.innerHeight - 70;
          that.divWidth = document.body.clientWidth;
        })();
      }
    },
    // 添加标注点。lonat：经纬度数组
    addMarker (lonlat, text, ) {
      var marker = new Feature({
        geometry: new Point(fromLonLat(lonlat))
      });
      marker.setStyle(new Style({
        image: new Icon({
          // 允许跨域，如果不设置，打印地图不会打印
          crossOrigin: 'anonymous',
          src: require('@/assets/images/marker-icon.png'),
          // 标注图片和文字之间的距离
          anchor: [0.5, 0],
          // 图片的偏移
          offset: [0.2, 0],
          // 图片的锚点，一般来说，都是右下角
          anchorOrigin: 'bottom-right',
          //图标比例, 0.5 大概是25*34
          scale: 1,
        }),
        text: new Text({
          text: text,
          // 偏移
          offsetX: 0,
          offsetY: -50,
          // 文字居中
          textAlign: 'center',
          // 字体
          font: 'normal bold  12px  Arial,sans-serif',
          // 比例
          scale: 1,
          // 边距
          padding: [5, 5, 5, 5],
          // 字体颜色
          fill: new Fill({
              color: '#333'
          }),
          // 背景色
          backgroundFill: new Fill({
              color: 'rgba(252,254,255, 0.8)'
          }),
          // 背景边框
          backgroundStroke: new Stroke({
              width: 0.2,
          }),
        })
      }));
      this.vecLayer.getSource().addFeature(marker);
      console.log('marker:', marker)
      // 监听地图层级变化
      this.map.getView().on('change:resolution', function () {
        var style = marker.getStyle();
        // 重新设置图标的缩放率，基于层级10来做缩放
        style.getImage().setScale(this.getZoom() / 10);
        marker.setStyle(style);
      })
    },
    // 处理地理编码查询结果
    handleGeocoder (result) {
      var lonlat = [];
      lonlat.push(result.location.lon);
      lonlat.push(result.location.lat);
      this.addMarker(lonlat, result.location.keyWord + '(' + result.location.level + ')');
      // 更换中心点
      this.changeCenterZoom(lonlat);
    },

    // 处理行政区划结果
    handleGovernment (result) {
      console.log(result)
      // 设置中心点和标注
      var lonlat = [result[0].lnt, result[0].lat];
      this.addMarker(lonlat, result[0].name);
      this.changeCenterZoom(lonlat);
      result.forEach( item => {

      })
    },
    changeCenterZoom (lnglat) {
      // 将标注点更换为中心点
      this.map.getView().animate({ // 只设置需要的属性即可
        center: fromLonLat(lnglat), // 中心点
        zoom: 16, // 缩放级别
        rotation: undefined, // 缩放完成view视图旋转弧度
        duration: 1000 // 缩放持续时间，默认不需要设置
      })
    },
    // 地理逆编码查询，根据坐标查询名称
    /* searchCoordinate (coordinates) {

      $.ajax({
        url: '/geocoder',
        type: 'get',
        contentType: "application/json;charset=UTF-8", //指定消息请求类型
        data: {
          // 注意参数格式
          postStr: JSON.stringify({
            // 坐标
            "lon": coordinates[0],
            "lat": coordinates[1],
            "ver": 1
          }),
          type: 'geocode',
          // 请更换自己的 tk，此 tk 只能在当前域名下使用
          tk: '9aa421bfac4b31f0ad91a7118973689d',
        },
        success: function (res, status) {


          res = JSON.parse(res);

          return res.result;
        },
      });
    }, */
    // 切换图层
    changeLayer (val) {
      if (val === 'vector' ) {
        this.map.setLayers([this.vec_layer, this.vecLayer]);
      } else {
        this.map.setLayers([this.img_layer, this.vecLayer]);
      }
      // this.addMarker(transform(this.map.getView().getCenter(), 'EPSG:3857', 'EPSG:4326'), '');
    }
  },
  mounted () {
    this.mapInit();
    this.computeHeight();
  },
  computed: {
    mapDivSize () {
      return {
        divHeight: this.divHeight,
        divWidth: this.divWidth
      }
    }
  },
  watch: {
    mapDivSize () {
      this.computeHeight();
    }
  }

}
</script>

<style lang="scss" scoped>
.map-div-xyz {
  position: relative;
}

#my-map {
  position: absolute;
  height: 100%;
  width: 100%;
}

.custom-mouse-position {
  position: absolute;
  padding: auto;
  z-index: 999;
  background: hsla(0,0%,100%,1);
  width: 160px;
  height: 1em;
  bottom: 0;
  left: 65%;
  opacity: 0.5;
  color: black;
}

.custom-zoom-position {
  position: absolute;
  width: 28px;
  height: 53px;
  bottom: 1em;
  right: 2em;
  z-index: 9999;
}
</style>